package edu.ncsu.csc.ip.sender;

import java.io.IOException;
import java.net.DatagramPacket;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class StopNWaitProtocol {

	SendClient sender;

	private long currentSequenceNumber = 0;
	TimeManager timeManager = new TimeManager(this);
	public static int HEADER_SIZE = 32;
	public static int ACK_HEADER_SIZE = 32;

	public StopNWaitProtocol(SendClient sender) {
		this.sender = sender;
	}

	ConcurrentHashMap<String, DatagramPacket> packetMap = new ConcurrentHashMap<String, DatagramPacket>();
	ConcurrentHashMap<String, SenderThread> threadPool = new ConcurrentHashMap<String, SenderThread>();

	public synchronized void packetSent(DatagramPacket packet) {
		packetMap.put(packet.getAddress().getHostAddress(), packet);
	}

	public synchronized void ackReceived(DatagramPacket packet) {
		if (packetMap.contains(packet.getAddress())
				&& getSequenceNumber(packetMap.get(packet.getAddress())) == getCurrentSequenceNumber()) {
			packetMap.remove(packet.getAddress().getHostAddress());
			if (packetMap.size() == 0) {
				timeManager.stop();
				sender.sendNext();

			}
		}

	}

	public long getSequenceNumber(DatagramPacket packet) {
		return 1l;
	}

	public void timoutOccured() {
		for (SenderThread thread : threadPool.values()) {
			if (thread.getSocket() != null)
				thread.getSocket().close();
		}
		threadPool.clear();
	}

	public void addThread(String address, SenderThread thread) {
		threadPool.put(address, thread);
	}

	public void sendAll(List<DatagramPacket> packets) throws IOException {
		for (DatagramPacket packet : packets) {
			SenderThread sThread = new SenderThread(packet.getAddress()
					.getHostAddress(), packet, this);
			addThread(packet.getAddress().getHostAddress(), sThread);
			sThread.start();
		}
	}

	public long getCurrentSequenceNumber() {
		return currentSequenceNumber;
	}

	
}
